package com.whity.towerdefense.model;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Log;

import com.whity.towerdefense.view.GraphicDrawable;
import com.whity.towerdefense.view.GraphicEltFactory;
import com.whity.towerdefense.view.GraphicHeart;

public class ShootType
{
	// =============================================================
	// Private attributs :
	
	private static final String		TAG = "com.djm.test03.model";
	
	// General attributs
	private String 					m_Name;
	private String					m_GraphicHeartPath;
	private String					m_RangeGraphicHeartPath;
	private float					m_Size;		// in Cell, diameter of the circle defining this shoot.
	
	// Statistic of the shoot
	private float					m_Range;
	private float					m_Damage;
	private float					m_FireRate;	// in shot per second
	private float					m_SplashRadius;
	private float					m_SplashReduction;
	private int						m_Bounce;
	private float					m_BounceReduction;
	
	// =============================================================
	// Private functions
	
	private ShootType(String p_Name, String p_GraphicHeartPath, String p_RangeGraphicHeartPath, float p_Size, float p_Range, float p_Damage, float p_FireRate, float p_SplashRadius, float p_SplashReduction, int p_Bounce, float p_BounceReduction)
	{
		m_Range					= p_Range;
		m_Damage				= p_Damage;
		m_FireRate 				= p_FireRate;
		m_SplashRadius			= p_SplashRadius;
		m_SplashReduction		= p_SplashReduction;
		m_Bounce				= p_Bounce;
		m_BounceReduction		= p_BounceReduction;
		m_Size 					= p_Size;
		m_GraphicHeartPath		= p_GraphicHeartPath;
		m_RangeGraphicHeartPath = p_RangeGraphicHeartPath;
	}
	
	// =============================================================
	// Public functions
	
	public ShootType(XmlPullParser p_XmlParser)
	{
		m_Name					= "";
		m_GraphicHeartPath 		= "";
		m_RangeGraphicHeartPath = "";
		m_Range					= -1;
		m_Damage				= 0;
		m_FireRate 				= -1;
		m_SplashRadius			= 0;
		m_SplashReduction		= 0;
		m_Bounce				= 0;
		m_BounceReduction		= 0;
		m_Size					= -1;
		
		try
		{
	        int eventType = p_XmlParser.getEventType();
	        
	        if(!p_XmlParser.getName().equals("ShotType") || eventType != XmlPullParser.START_TAG)
        	{
	        	Log.e(TAG, "Xml mark wrong. Can't initialise a ShotType: " +  p_XmlParser.getName() + " : " + eventType);
	        	return;
        	}
	        
	        while(eventType != XmlPullParser.END_DOCUMENT)
	        {
	        	
	        	if(eventType == XmlPullParser.START_TAG)
	            {
	        		if(p_XmlParser.getName().equals("ShotType"))
	            	{
	        			m_Name 				= p_XmlParser.getAttributeValue(null, "Name");
	        			m_GraphicHeartPath	= p_XmlParser.getAttributeValue(null, "Graphic");
	        			GraphicEltFactory.CreateGraphicElt(m_GraphicHeartPath);
	        			m_RangeGraphicHeartPath	= p_XmlParser.getAttributeValue(null, "GraphicRange");
	        			GraphicEltFactory.CreateGraphicElt(m_RangeGraphicHeartPath);
	        			m_Range				= Float.parseFloat(p_XmlParser.getAttributeValue(null, "Range"));
	        			m_Damage			= Float.parseFloat(p_XmlParser.getAttributeValue(null, "Damage"));
	        			m_FireRate 			= Float.parseFloat(p_XmlParser.getAttributeValue(null, "Rate"));
	        			m_SplashRadius 		= (p_XmlParser.getAttributeValue(null, "SplashRadius") == null)?0:Float.parseFloat(p_XmlParser.getAttributeValue(null, "SplashRadius"));
	        			//m_SplashRadius	= Float.parseFloat(p_XmlParser.getAttributeValue(null, "SplashRadius"));
	        			m_SplashReduction 	= (p_XmlParser.getAttributeValue(null, "SplashReduc") == null)?0:Float.parseFloat(p_XmlParser.getAttributeValue(null, "SplashReduc"));
	        			//m_SplashReduction	= Float.parseFloat(p_XmlParser.getAttributeValue(null, "SplashReduc"));
	        			m_Bounce 			= (p_XmlParser.getAttributeValue(null, "Bounce") == null)?0:Integer.parseInt(p_XmlParser.getAttributeValue(null, "Bounce"));
	        			//m_Bounce			= Integer.parseInt(p_XmlParser.getAttributeValue(null, "Bounce"));
	        			m_BounceReduction 	= (p_XmlParser.getAttributeValue(null, "BounceReduc") == null)?0:Float.parseFloat(p_XmlParser.getAttributeValue(null, "BounceReduc"));
	        			//m_BounceReduction	= Float.parseFloat(p_XmlParser.getAttributeValue(null, "BounceReduc"));
	        			m_Size			 	= (p_XmlParser.getAttributeValue(null, "Size") == null)?1.0f:Float.parseFloat(p_XmlParser.getAttributeValue(null, "Size"));
	            	}
	            }
	        	eventType = p_XmlParser.next();
	        }
		}
		catch (IOException e)
	    {
	    	Log.w(TAG, e.toString());
		}
		catch (XmlPullParserException e)
		{
			Log.w(TAG, e.toString());
		}
	}
	
	/**
	 * Intent to shoot.
	 * The center of the shoot source is precized by p_X, p_Y.
	 * @param p_X X coordinate of the source of the shoot
	 * @param p_Y Y coordinate of the source of the shoot
	 * @return True if a shoot of fired, false otherwise.
	 */
	public boolean Shoot(float p_X, float p_Y)
	{
		boolean res = false;
		Map map = GameModel.LEVEL.GetMap();
		List<Unit> units = map.GetUnits();
		
		for(Unit target : units)
		{
			if((target.GetPosition().x-p_X)*(target.GetPosition().x-p_X)+(target.GetPosition().y-p_Y)*(target.GetPosition().y-p_Y) <= (m_Range/2.0f)*(m_Range/2.0f))
			{
				Shoot shoot = CreateShoot(p_X, p_Y, target);
				res = true;
				GameModel.LEVEL.AddShoot(shoot);
				break;
			}
		}
		
		return res;
	}
	
	public Shoot CreateShoot(float p_X, float p_Y, Unit p_Target)
	{
		return new Shoot(m_Name, m_Size, m_Range, m_Damage, m_SplashRadius, m_SplashReduction, m_Bounce, m_BounceReduction, GraphicEltFactory.GetGraphicHeart(m_GraphicHeartPath), p_X, p_Y, p_Target);
	}
	
	public ShootType Clone()
	{
		return new ShootType(m_Name, m_GraphicHeartPath, m_RangeGraphicHeartPath, m_Size, m_Range, m_Damage, m_FireRate, m_SplashRadius, m_SplashReduction, m_Bounce, m_BounceReduction);
	}
	
	public String GetName()
	{
		return m_Name;
	}

	public String GetRangeGraphicHeartPath()
	{
		return m_RangeGraphicHeartPath;
	}
	
	public float GetFireRate()
	{
		return m_FireRate;
	}
	
	public float GetRange()
	{
		return m_Range;
	}
	
	// =============================================================
}
